
import { Utils } from "../utils/utils.js";

// type Validator = '' | 'blacklist' | 'whitelist';

// interface RouteOptions {
// 	// 入场设置
// 	in?: UniNamespace.NavigateToOptions,
// 	// 出场设置
// 	out?: UniNamespace.NavigateBackOptions,
// 	// 黑名单
// 	blacklist?: string[],
// 	// 白名单
// 	whitelist?: string[],
// 	// 验证函数
// 	validFn?: ()=>boolean | null,
// 	// 验证方案
// 	validators?: Validator[],
// }


export class Route {
	/** 入场设置 */
	inOptions = {
		animationType: 'pop-in',
		animationDuration: 300,
		url: '',
	};
	/** 出场设置 */
	outOptions = {
		delta: 1,
		animationType: 'pop-out',
		animationDuration: 300,
	};
	/** 黑名单 */
	blacklist = [];
	/** 白名单 */
	whitelist = [];
	/** 验证函数 */
	validFn = () => true;
	/** 验证方案 'blacklist' | 'whitelist' */
	validators = [''];

	tabInterceptor = () => {
		return {
			invoke: (args) => {
				return this.check({ url: args.url });
			},
		};
	};

	constructor(option = {}) {
		this.inOptions = option.in ?? {
			animationType: 'pop-in',
			animationDuration: 300,
			url: '',
		};
		this.outOptions = option.out ?? {
			delta: 1,
			animationType: 'pop-out',
			animationDuration: 300,
		};
		if (Utils.isArray(option.blacklist) && option.blacklist.length > 0) {
			this.blacklist = option.blacklist;
		}
		if (Utils.isArray(option.whitelist) && option.whitelist.length > 0) {
			this.whitelist = option.whitelist;
		}
		if (Utils.isFunction(option.validFn)) {
			this.validFn = option.validFn;
			/**
			 * @注意 小程序'switchTab'无法拦截
			 * */
			uni.addInterceptor('switchTab', this.tabInterceptor());
		}
		if ((Utils.isArray(option.validators) && option.validators.length > 0)) {
			this.validators = option.validators;
		}
		
		
	}
	/**
	 * 白名单验证
	 * */
	checkWhitelist = (url) => {
		const hasWhitelist = !!~this.whitelist.findIndex(v => v === url);
		if (hasWhitelist === false) {
			return this.validFn();
		}
		return true;
	};
	/**
	 * 黑名单验证
	 * */
	checkBlacklist = (url) => {
		const hasBlacklist = !!~this.blacklist.findIndex(v => v === url);
		if (hasBlacklist) {
			return this.validFn();
		}
		return true;
	};

	/**
	 * 验证路由
	 * @param {{url: String}} params
	 * @returns {Boolean}
	 * */
	check = (params) => {
		const url = params.url || '';
		const newUrl = url.replace(/\?[\d|\D]+/g, '');
		let result = true;
		this.validators.forEach(v => {
			switch (v) {
				case 'blacklist':
					result = this.checkBlacklist(newUrl);
					break;
				case 'whitelist':
					result = this.checkWhitelist(newUrl);
					break;
				default:
					break;
			}
		});
		return result;
	};

	/**
	 * 保留当前页面，跳转到应用内的某个页面
	 * @param {String} url 
	 * @returns {Promise<boolean>}
	 */
	push = (url) => {
		if (this.check({ url }) === false) {
			return Promise.resolve(false);
		}
		return new Promise((resolve) => {
			uni.navigateTo({
				url: url,
				animationType: this.inOptions.animationType,
				animationDuration: this.inOptions.animationDuration,
				success: () => {
					resolve(true);
				},
				fail: (e) => {
					console.log(e);
					resolve(false);
				},
			});
		});
	}

	/**
	 * 关闭当前页面，返回上一页面或多级页面。
	 * @returns {Promise<boolean>}
	 */
	pop = () => {
		return new Promise((resolve) => {
			uni.navigateBack({
				delta: 1,
				animationType: this.outOptions.animationType,
				animationDuration: this.outOptions.animationDuration,
				success: () => {
					resolve(true);
				},
				fail: () => {
					resolve(false);
				},
			});
		});
	}

	/**
	 * 跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面。
	 * @param {String} url 
	 * @returns {Promise<boolean>}
	 */
	tab = (url) => {
		if (this.check(url) === false) {
			return Promise.resolve(false);
		}
		return new Promise((resolve) => {
			uni.switchTab({
				url: url,
				success: () => {
					resolve(true);
				},
				fail: () => {
					resolve(false);
				},
			});
		});
	}

	/**
	 * 关闭当前页面，跳转到应用内的某个页面。
	 * @param {String} url 
	 * @returns {Promise<boolean>}
	 */
	redirectTo = (url) => {
		if (this.check({ url }) === false) {
			return Promise.resolve(false);
		}
		return new Promise((resolve) => {
			uni.redirectTo({
				url: url,
				success: () => {
					resolve(true);
				},
				fail: () => {
					resolve(false);
				},
			});
		});
	};

	/**
	 * 关闭所有页面，打开到应用内的某个页面。
	 * @param {String} url 
	 * @returns {Promise<boolean>}
	 */
	reLaunch = (url) => {
		return new Promise((resolve) => {
			uni.reLaunch({
				url: url,
				success: () => {
					resolve(true);
				},
				fail: () => {
					resolve(false);
				},
			});
		});
	}
}